package com.stylefeng.guns.core.util;

import org.apache.commons.beanutils.BeanMap;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.IntStream;

/**
 * 通用工具类
 *
 * @author wuchong
 */
public class CommonUtil {

    /**
     * @param x          表示某一事件出现的次数
     * @param mean       期望值
     * @param cumulative 表示确定返回的概率分布形式的逻辑值。若cumulative为TRUE，则函数返回泊松累积分 布概率，即随机事件发生的次数在0~之间(包含0~1);
     *                   若cumulative为FALSE，则函数返回泊 松概率密度函数，即随机事件发生的次数恰好为x。
     * @return
     */
    public static double poisson(int x, double mean, boolean cumulative) {

        if (cumulative) {
            return IntStream.rangeClosed(0, x).mapToDouble(value -> poisson(value, mean)).sum();
        } else {
            return poisson(x, mean);
        }
    }


    private static double poisson(int x, double mean) {
        if (x == 0) {
            return Math.exp(-mean);
        }
        return (mean / x) * poisson(x - 1, mean);
    }

    /**
     * 计算胜赔
     *
     * @param n
     * @param mean1 期望值1
     * @param mean2 期望值2
     * @return
     */
    public static double calWinProbability(int n, double mean1, double mean2) {
        if (n == 0) {
            return 0;
        }
        return calWinProbability(n - 1, mean1, mean2) + poisson(n, mean1, false) * poisson(n - 1, mean2, true);
    }

    /**
     * 将Bean对象转换成Map对象，将忽略掉值为null或size=0的属性
     *
     * @param obj 对象
     * @return 若给定对象为null则返回size=0的map对象
     */
    public static Map<String, Object> toMap(Object obj) {
        Map<String, Object> map = new LinkedHashMap<>();
        if (obj == null) {
            return map;
        }
        BeanMap beanMap = new BeanMap(obj);
        Iterator<String> it = beanMap.keyIterator();
        while (it.hasNext()) {
            String name = it.next();
            Object value = beanMap.get(name);
            // 转换时会将类名也转换成属性，此处去掉
            if (value != null && !name.equals("class")) {
                map.put(name, value);
            }
        }
        return map;
    }

    public static void main(String[] args) {
        System.out.println(poisson(100, 2.5, true));
    }

}
